<?php
/**
 * Created by PhpStorm.
 * User: guokunsheng
 * Date: 2018/6/14
 * Time: 10:26
 */

namespace app\common\lib;

use app\common\cachemodel\AppConfig;
use app\common\cachemodel\Orders as OrdersCacheModel;
use app\common\cachemodel\Recode;
use app\common\model\MessageCenter;
use app\common\model\Orders;
use app\common\model\User;
use think\Log;
use think\queue\job;
use app\common\model\Rectification as RectificationModel;

/**
 * 校准生辰任务管理
 * Class RectificationJob
 * @package app\common\lib
 */
class RectificationJob
{
    /**
     * @param job $job
     * @param $data
     * @throws \think\exception\DbException
     * @throws exception\ApiException
     */
    public function task1(Job $job, $data)
    {
        $jobAttempts = $job->attempts();
        if ($jobAttempts > 1)
        {
            $job->delete();
        }

        $host = Util::getEcsIp();
        $startTime = date('Y-m-d H:i:s');
        $logInfo = "校准生辰计算 开始:{$startTime} host:{$host} uid:{$data['recode']['uid']} rid:{$data['recode']['id']} name:{$data['recode']['name']}";
//        \think\Log::write('校准生辰开始时间:' . date('Y-m-d H:i:s'), 'log', true);
        // \think\Log::write('校准生辰数据:'.var_export($data,true),'log',true);
        // 总共执行次数  最多120次（每分钟一个星盘）
        $OrdersModel = new Orders();
        $n = ceil($data['end_time'] - $data['start_time']) / 60;
        $events = [];
        for ($i = 0; $i < $n; $i++)
        {
            // 每分钟一个
            $birth_time = $data['start_time'] + $i * 60;

            $events[date('Y-m-d H:i', $birth_time)] = (new Rectification())->getValidEventsScore($data['events'], $birth_time, $data['recode']);
        }

        $events = array_filter($events);

        $reid = $data['reid'];

        $status = 2;
        $result_all = [];

        if (empty($events))
        {
//            \think\Log::write('校准生辰失败时间:' . date('Y-m-d H:i:s'), 'log', true);
            $logInfo .= ' error: 校准生辰失败，无结果';

            $status = 3;
        } else
        {
            array_multisort($events, SORT_NUMERIC, SORT_DESC);

            $result = array_slice($events, 0, 3, true);

            // 两个原则：1，优先接近用户原本时间的结果；
            // 2，优先与用户原上升星座相同的结果
            // 如果最高得分满足与原上升相同且在差距不超过十分钟这个条件，定位最佳结果，
            // 如果有多个，则最接近原时间的是最佳结果。
            // 如果最高得分不同时满足以上条件，优先在十分钟之内的，
            // 如没有则选择同上升的。同上升条件下选择更接近原时间的。

            // 统计各值在数组中出现的次数
            // $count_result = array_count_values($events);

            // \think\Log::write('校准生辰结果统计:'. var_export($count_result,true),'log',true);

            $n = 0;
            foreach ($result as $k => $r)
            {
                if ($n == 1) $r--;
                elseif ($n == 2) $r -= 2;
                $result_all[] = ['time' => strtotime($k), 'score' => $r, 'reid' => $reid, 'status' => 0];
                $n++;
            }

            if (empty($result_all))
            {
                $status = 3;
            }

//            \think\Log::write('校准生辰结果:' . var_export($result, true), 'log', true);
//            \think\Log::write('任务执行次数:' . $job->attempts(), 'log', true);
//            \think\Log::write('校准生辰结束时间:' . date('Y-m-d H:i:s'), 'log', true);
        }

        try
        {
            $rectification = RectificationModel::get($reid);
            $user = (new User())->getUserinfo(['id' => $rectification['uid']]);
//            $rectification->isUpdate(true)->save(['status' => $status, 'result_time' => time()]);
            //更新校准生辰2.0缓存
            (new \app\common\cachemodel\Rectification())->saveRec($rectification['uid'], $reid, ['status' => $status, 'result_time' => time()], [], $result_all);
            //更新2.0订单缓存
            (new OrdersCacheModel())->UpdateData($data['order_id'], ['status' => 4], 4);
            // 删除订单缓存
            $OrdersModel->rm_cache([
                'oid' => $data['oid'],
                'del_add' => 0,
                'order_id' => $data['order_id'],
                'uid' => $user['id']
            ]);
        }
        catch (\Exception $e)
        {
            $logInfo .= ' error:' . $e->getMessage() . ' file:' . $e->getFile() . ':' . $e->getLine();
//            \think\Log::write('校准生辰结果入库失败:' . $e->getMessage(), 'log', true);
            $rectification = RectificationModel::get($reid);
            $rectification->isUpdate(true)->save(['status' => 3]);
//            $OrdersModel->isUpdate(true)->save(['status' => 5], ['id' => $data['oid']]);
        }
        if (!empty($user) && $user && isset($data['push_switch']) && $data['push_switch'])
        {
            // APP推送
            // if (isset($user['regid']) && $user['regid'] != '')
            // {
            //     (new Push())->pushSpecial($user['regid'], '您提交的校准生辰已经完成了，点击查看校正结果！', ['action' => 'rectification_details', 'id' => $reid]);
            // }
            $recodeStatus = (new Recode())->getInfoById($data['recode']['id'], ['status']);
            $link = $recodeStatus['status']
                ?  'rectification_details?id=' . $reid . '&need_auth=1'
                :  "order_details?order_id={$data['order_id']}&order_type=1&need_auth=2";

            $pushRes = (new Push())->pushUserMsg($user['id'], '您提交的校准生辰已经完成了，点击查看校正结果！', ['target' => 'local', 'link' => $link, 'action' => 'extend']);
            if (!$pushRes['success'])
            {
//                print('校准生辰完成->推送失败' . PHP_EOL);
//                \think\Log::write('校准生辰完成->推送失败: ' . PHP_EOL . var_export($pushRes['message'], true) . PHP_EOL, 'error', true);
                $logInfo .= ' error: 计算完成,推送失败 message:' . $pushRes['message'];
            }
            // 短信通知
            if (config('queue.rectification_sendms') && isset($user['tel']) && $user['tel'] != '')
            {
                $alidayu = (new AppConfig())->configInfo('alidayu');
                sendSms($user['tel'], [], $alidayu['rectification_code']);
            }
            // 消息中心添加信息
            $mag = [
                'status' => 0,
                'is_read' => 0,
                'range' => $user['id'],
                'type' => 2,
                'reid' => $reid,
                'cid' => 1,
                'title' => '校准生辰结果',
                'content' => '您提交的校准生辰已经完成了，点击查看校正结果！',
                'link' => 'rectification_details?id=' . $reid . '&need_auth=1',
                'target' => 'local',
                'create_time' => time()
            ];
            $new_recode[] = [
                'rid' => $data['recode']['id']
            ];
            //添加消息
            (new MessageCenter())->pushMessage($user['id'], $mag);
        }

        //如果任务执行成功后 记得删除任务，不然这个任务会重复执行，直到达到最大重试次数后失败后，执行failed方法
        $job->delete();

        $logInfo .= ' jobData:' . json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        print(date('Y-m-d H:i:s') . ' ' . $logInfo);
        Log::write($logInfo, 'log', true);
    }

    public function failed($data)
    {
        // ...任务达到最大重试次数后，失败了


        // 重新发布任务
//        \think\Queue::push('app\common\lib\Job@task1', $data, 'rectification');
    }
}
